{-# LANGUAGE NamedFieldPuns, DeriveDataTypeable, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TemplateHaskell, UndecidableInstances  #-}
module State.Database(UserId(..),
                      SubmissionId(..),
                      ProblemId(..),
                      UserInfo(..),
                      Language(..),
                      Program(..),
                      SubmissionInfo(..),
                      ProblemInfo(..),
                      TestInfo(..),
                      TuuraDb(..)) where

import Happstack.Data            (Default, Version, deriveAll, deriveSerialize)
import System.Time               (ClockTime)
import Happstack.State.ClockTime () -- instance Data ClockTime
import Data.Map(Map)
import Control.Applicative
import Prelude hiding (id,toInteger)
import Happstack.Data.Serialize (Mode(..), mode)

$(deriveAll [''Show, ''Eq, ''Ord, ''Default]
  [d|
      newtype UserId = UserId { openId :: String }
      newtype SubmissionId = SubmissionId Integer
      newtype ProblemId = ProblemId Integer
      data UserInfo = UserInfo {
      }

      data Language = Haskell | Cpp | CSharp | Java

      data Program = Program { programLanguage :: Language, programCode :: String }

      data SubmissionInfo = SubmissionInfo {
        submissionContent :: Program,
        submissionProblem :: ProblemId,
        submissionDate :: ClockTime
      }

      data ProblemInfo = ProblemInfo {
        problemName :: String,
        problemStatement :: String,
        testValidator :: Program,
        referenceSolution :: Program
      }

      data TestInfo = TestInfo {
        testContent :: String
      }

      data TuuraDb = TuuraDb {
--        users :: Map UserId UserInfo,
        submissions :: Map SubmissionId SubmissionInfo,
        problems :: Map ProblemId ProblemInfo
      }
   |])

instance Version TuuraDb
instance Version SubmissionId
instance Version ProblemId
instance Version SubmissionInfo
instance Version ProblemInfo where
    mode = Versioned 1 Nothing

instance Version Language
instance Version Program
$(concat <$> mapM deriveSerialize [''TuuraDb, ''SubmissionId, ''ProblemId, ''SubmissionInfo, ''ProblemInfo,  ''Language, ''Program])
